#include "stdafx.h"
#include "Renderer.h"

#include "GraphicsComponent.h"
#include "GraphicsRepresentation.h"

namespace Cinetic
{


	Renderer::Renderer( HWND hWnd, HINSTANCE hInstance )
	{
		m_ogre_root = new Ogre::Root("plugins_d.cfg");
		m_render_system = new Ogre::D3D9RenderSystem(hInstance);
		m_ogre_root->setRenderSystem(m_render_system);
		m_ogre_root->initialise(false, "Cinetic");


		Ogre::NameValuePairList windowParams;
		windowParams["externalWindowHandle"] = Ogre::StringConverter::toString((unsigned int)hWnd);
		m_render_window = m_ogre_root->createRenderWindow("Cinetic", 1024, 720, false, &windowParams);

		m_scene_manager = m_ogre_root->createSceneManager(Ogre::ST_GENERIC);

		m_camera = m_scene_manager->createCamera("Camera");
		m_camera->setPosition(Ogre::Vector3(0,0,50));
		m_camera->lookAt(Ogre::Vector3(0,0,0));
		m_camera->setNearClipDistance(5);

		m_viewport = m_render_window->addViewport(m_camera);
		m_viewport->setBackgroundColour(Ogre::ColourValue(0.0,0.0,0.0));

		m_camera->setAspectRatio(Ogre::Real(m_viewport->getActualWidth())/Ogre::Real(m_viewport->getActualHeight()));

		load_resources();

	}

	Renderer::~Renderer()
	{
		delete m_ogre_root;
	}

	void Renderer::load_resources()
	{
		//Loads all the resources specified externally in the resources.cfg or resources_d.cfg config files
		Ogre::ConfigFile cf;
#ifdef _DEBUG
		cf.load("resources_d.cfg");
#else
		cf.load("resources.cfg");
#endif
		Ogre::ConfigFile::SectionIterator sectionIter =	cf.getSectionIterator();

		Ogre::String sectionName, typeName, dataname;
		while (sectionIter.hasMoreElements()) {
			sectionName = sectionIter.peekNextKey();
			Ogre::ConfigFile::SettingsMultiMap *settings = sectionIter.getNext();
			Ogre::ConfigFile::SettingsMultiMap::iterator i;
			for (i = settings->begin(); i != settings->end(); ++i) {
				typeName = i->first;
				dataname = i->second;
				Ogre::ResourceGroupManager::getSingleton().addResourceLocation(dataname, typeName, sectionName);
			}
		}

		Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
	}

	void Renderer::draw()
	{
		m_ogre_root->renderOneFrame();
	}

	std::shared_ptr<Representation> Renderer::create_representation( std::weak_ptr<Object> o )
	{
        auto g = std::dynamic_pointer_cast<GraphicsComponent>(o.lock());
        if (g) {

            std::shared_ptr<GraphicsRepresentation> r = std::make_shared<GraphicsRepresentation>(g, m_scene_manager);
            return r;
        }

        return nullptr;
	}

}